<template>
  <div class="map-wrap">
    <div class="full-map" :id="geoMapEChartId"></div>
  </div>
</template>
<script lang="ts">
  import {
    defineComponent,
    toRefs,
    reactive,
    ref,
    onMounted,
    onUnmounted,
    onBeforeUnmount,
    watch,
    nextTick,
  } from 'vue';
  import * as echarts from 'echarts';
  import _ from 'lodash';
  //引入axios用于读取本地geo的json文件
  import axios from 'axios';

  export default defineComponent({
    name: 'EchartsYunnanGeoMapTest',
    components: {},
    props: {
      geoJson: Object, //通过父组件传入map中的geo属性数据
      echartData: Object, //通过父组件传入echart中option配置
      chartName: { type: String, default: '' },
      isRoll: Boolean,
      showLoading: { type: Boolean, default: true }, //是否要显示loading
    },
    setup(props, context) {
      // console.log('EchartsGeoMap.vue setup props.geoJson', props.geoJson);
      // console.log('EchartsGeoMap.vue setup props.echartData', props.echartData);
      let myEchart = null;
      //窗口变化监听,避免resize多次执行卡顿
      var resizeTimer = null;
      const state = reactive({
        heightChart: 0,
        geoJson: props.geoJson,
        data: props.echartData, //options
        interval: null,
        geoMapEChartId: props.chartName + Math.ceil(Math.random() * 100000000).toString(),
        observer: null,
      });

      function loadMapFromJsonFile(filename) {
        axios
          .get('/resource/geo/' + filename + '.json')
          .then((res) => {
            // ehsGeoMapGeoJson.value = res.data;
            console.log('axios.get geo response' + res);

            echarts.registerMap(filename, { geoJSON: res.data });

            let option = {
              title: {
                show: false,
                text: 'yunnan',
                left: 'center',
              },
              //地理坐标系组件
              geo: {
                type: 'map',
                map: 'yunnan',
                // rotation: 45, // 设置旋转角度为 45 度，设置无效
                //启用平移缩放
                roam: true,
                //滚轮缩放的极限控制
                scaleLimit: {
                  min: 0.5,
                  max: 3,
                },
                //当前视角的缩放比例
                //zoom :1.2,
                //设置地图的长宽比，应该根据实际地图的比例来设置或者不设置，设置值不正确会导致地图变形
                // aspectScale: 0.7,
                //设置geo地图的位置和大小
                // layoutCenter: ['50%', '55%'],
                layoutCenter: ['46.5%', '57%'],
                layoutSize: '80%',
                zlevel: 1,
                //图形上的文本标签，可用于说明图形的一些数据信息，比如值，名称等
                label: {
                  show: true,
                  color: '#75d1f0',
                  fontSize: 12,
                  formatter: (p) => {
                    return p.name;
                  },
                  //offset:[0,10],
                },
                //地图区域的多边形 图形样式
                itemStyle: {
                  //图形的描边颜色
                  borderColor: new echarts.graphic.LinearGradient(
                    0,
                    0,
                    0,
                    1,
                    [
                      { offset: 0, color: '#0a94c2' },
                      { offset: 1, color: '#0982a9' },
                    ],
                    false,
                  ),
                  borderWidth: 2,
                  //阴影颜色
                  shadowColor: '#0f6b8a',
                  // shadowColor: 'rgba(9, 89, 169, 0.8)',
                  //阴影水平、垂直方向上的偏移距离；设置后会有立体效果
                  shadowOffsetX: 0,
                  shadowOffsetY: 0,
                  //图形阴影的模糊大小
                  shadowBlur: 10,
                  //地图区域的颜色
                  areaColor: {
                    x: 0,
                    y: 0,
                    x2: 0,
                    y2: 1,
                    colorStops: [
                      { offset: 0, color: 'rgba(9, 89, 169, 0.5)' },
                      { offset: 1, color: 'rgba(3, 25, 48, 0.5)' },
                    ],
                  },
                },
                //选中状态下的多边形和标签样式
                select: {
                  label: {
                    show: true,
                    color: '#ffffff',
                    fontSize: 15,
                  },
                  itemStyle: {
                    areaColor: {
                      x: 0,
                      y: 0,
                      x2: 0,
                      y2: 1,
                      colorStops: [
                        { offset: 0, color: 'rgba(15, 185, 242, 0.2)' },
                        { offset: 1, color: 'rgba(7, 63, 121, 0.2)' },
                      ],
                    },
                  },
                },
                //高亮状态下的多边形和标签样式
                emphasis: {
                  label: {
                    color: '#ffffff',
                    fontSize: 14,
                    show: true,
                  },
                  itemStyle: {
                    areaColor: {
                      x: 0,
                      y: 0,
                      x2: 0,
                      y2: 1,
                      colorStops: [
                        { offset: 0, color: 'rgba(15, 185, 242, 0.5)' },
                        { offset: 1, color: 'rgba(7, 63, 121, 0.5)' },
                      ],
                    },
                  },
                },
              },
              series: [],
            };

            myEchart.setOption(option);
          })
          .catch((ex) => {
            console.log('axios.get geo catch', ex);
          });
      }

      /**
       * 监听元素变化
       */
      const domChange = () => {
        let selfChart = document.getElementById(state.geoMapEChartId);
        state.observer = new ResizeObserver(() => {
          myEchart.resize(); //ecahrts重置尺寸
        });
        state.observer.observe(selfChart); // 监听元素
      };
      /**监听数据改变,重新渲染 */
      watch(
        () => _.cloneDeep(props.echartData),
        (newProps) => {
          state.data = newProps;
          if (myEchart) {
            if (props.showLoading) {
              myEchart.showLoading();
              setTimeout(() => {
                myEchart.setOption(state.data);
                if (props.showLoading) {
                  myEchart.hideLoading();
                }
              }, 200);
            } else {
              myEchart.setOption(state.data);
            }
          }
        },
        { deep: true },
      );
      const setOptions = function () {
        myEchart.showLoading();
        setTimeout(() => {
          if (state.data) {
            myEchart.setOption(state.data);
            myEchart.getZr().on('click', function (param) {
              context.emit('backView', param);
            });
            myEchart.on('legendselectchanged', function (params) {
              context.emit('legendselectchanged', params);
            });
            myEchart.on('datazoom', function (params) {
              context.emit('datazoom', params);
            });

            if (props.isRoll) {
              if (state.data.dataZoom != null && state.data.dataZoom.length > 0) {
                if (state.data.dataZoom[0].endValue == state.data.yAxis[0].data.length) {
                  state.data.dataZoom[0].endValue = 4;
                  state.data.dataZoom[0].startValue = 0;
                } else {
                  state.data.dataZoom[0].endValue = state.data.dataZoom[0].endValue + 1;
                  state.data.dataZoom[0].startValue = state.data.dataZoom[0].startValue + 1;
                }
                myEchart.setOption(state.data);
              }
            }
            myEchart.hideLoading();
          }
        }, 300);
      };

      onMounted(() => {
        //测试地图，直接从json文件加载地图并显示
        loadMapFromJsonFile('yunnan');
        //先要使用registerMap注册地图，然后才能使用setOptions方法
        // getGeoJson('yunnan');
        // echarts.registerMap('china', { geoJSON: geoJson });
        myEchart = echarts.init(document.getElementById(state.geoMapEChartId));
        // setOptions();
        // domChange();
      });
      return {
        ...toRefs(state),
      };
    },
  });
</script>
<style scoped lang="less">
  .map-wrap {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;

    .full-map {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      z-index: 5;
      background-color: transparent;
    }
  }
</style>
